package com.incar.chuxing.activity;

import android.Manifest;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.AbsoluteSizeSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.google.gson.Gson;
import com.incar.chuxing.R;
import com.incar.chuxing.api.ApiStore;
import com.incar.chuxing.api.UrlConstant;
import com.incar.chuxing.baiduMap.LocationFilter;
import com.incar.chuxing.baiduMap.MapStatusUtils;
import com.incar.chuxing.baiduMap.PolygonUtils;
import com.incar.chuxing.base.BaseActivity;
import com.incar.chuxing.bean.CarBleBaojiaBean;
import com.incar.chuxing.bean.CarBleBean;
import com.incar.chuxing.bean.CityBoundBean;
import com.incar.chuxing.bean.OperateBean;
import com.incar.chuxing.bean.TravelDetailBean;
import com.incar.chuxing.ble.ViseBluetooth;
import com.incar.chuxing.ble.bean.CommandBleDbBean;
import com.incar.chuxing.ble.bean.OrderCmd;
import com.incar.chuxing.ble.callback.IConnectCallback;
import com.incar.chuxing.ble.callback.data.ICharacteristicCallback;
import com.incar.chuxing.ble.callback.scan.PeriodScanCallback;
import com.incar.chuxing.ble.enmu.ControlCmd;
import com.incar.chuxing.ble.enmu.MsgSendType;
import com.incar.chuxing.ble.exception.BleException;
import com.incar.chuxing.ble.helper.ICallBackCmd;
import com.incar.chuxing.ble.helper.IParseResultCallback;
import com.incar.chuxing.ble.manager.BLESendManager;
import com.incar.chuxing.ble.manager.DeviceControlManager;
import com.incar.chuxing.ble.manager.ParseManager;
import com.incar.chuxing.ble.model.BluetoothLeDevice;
import com.incar.chuxing.ble.utils.BleUtil;
import com.incar.chuxing.ble.utils.Logger;
import com.incar.chuxing.ble.utils.StringUtils;
import com.incar.chuxing.utils.AppManager;
import com.incar.chuxing.utils.Constants;
import com.incar.chuxing.utils.IntentKey;
import com.incar.chuxing.utils.Dialogs.InCarDialog;
import com.incar.chuxing.utils.MyApplication;
import com.incar.chuxing.utils.SharedPreferencesKey;
import com.incar.chuxing.utils.SharedPreferencesUtils;
import com.incar.chuxing.utils.TimeUtils;
import com.incar.chuxing.utils.Toast.ToastCompat;
import com.tencent.tinker.loader.shareutil.SharePatchFileUtil;

import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.OnClick;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static com.incar.chuxing.utils.Constants.readCharacteristicUUID;
import static com.incar.chuxing.utils.Constants.readServiceUUID;
import static com.incar.chuxing.utils.Constants.writeCharacteristicUUID;
import static com.incar.chuxing.utils.Constants.writeServiceUUID;

public class DrivingActivity extends BaseActivity implements SensorEventListener, ICallBackCmd {

    @BindView(R.id.textView_inUse_time)
    TextView textViewInUseTime;
    @BindView(R.id.imageButton_inUse_lockOff)
    ImageButton imageButtonInUseLockOff;
    @BindView(R.id.imageButton_inUse_lockOn)
    ImageButton imageButtonInUseLockOn;
    @BindView(R.id.textView_inUse_dropOffCar)
    TextView tVInUseDropOffCar;
    @BindView(R.id.imageButton_inUse_findCar)
    ImageButton imageButtonInUseFindCar;
    @BindView(R.id.tv_inUse_license)
    TextView tvInUseLicense;
    @BindView(R.id.progress_bar_in_use)
    RelativeLayout progressBarInUse;
    @BindView(R.id.imageView_refresh)
    ImageView imageView_refresh;
    @BindView(R.id.title_name)
    TextView title_name;
    @BindView(R.id.title_tv_more)
    TextView title_tv_more;
    @BindView(R.id.title_back)
    ImageView title_back;
    @BindView(R.id.tv_inUse_brand)
    TextView tv_inUse_brand;

    private MapView mapView;
    private BaiduMap mBaiduMap;
    private MapStatusUtils mapStatusUtils;
    private SensorManager mSensorManager;
    private Double lastX = 0.0;
    private int mCurrentDirection = 0;
    private MyLocationData locData;
    private float mCurrentAccracy;
    public LocationClient mLocClient = null;
    public MyLocationListener myListener = new MyLocationListener();
    private static boolean isExit = false;
    private LatLng curPosition;
    private Context mContext = this;
    private static String orderId;
    private String carId;
    private String carLicense;
    private String parkId;
    private long count = 0;
    private TimerTask task;
    private Timer timer;
    private PolygonUtils polygonUtils;
    private PowerManager.WakeLock wakeLock;
    private List<List<CityBoundBean.AttachmentBean>> cityBoundsInfo;
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    count++;
                    if (count > 86400) {
                        textViewInUseTime.setText(getSpannableString(TimeUtils.formatMinPlusOne(count + "")));
                    } else {
                        textViewInUseTime.setText(TimeUtils.formatSecondCount(count + "", 1));
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    };
    private boolean isFirstLocation = true;

    @Override

    public int getLayoutId() {
        return R.layout.activity_car_driving;
    }


    @Override
    public void initCustomMapView() {
        // new MapStatusUtils().setMapCustomFile(this, "custom_config.json");
    }

    @Override
    public void initView() {
        title_name.setText("行驶中");
        title_tv_more.setText("联系客服");
        title_back.setVisibility(View.GONE);
        initMap();
        startLocation();
    }

    @Override
    public void initData() {
        super.initData();
        Intent intent = getIntent();
        orderId = intent.getStringExtra(IntentKey.INTENT_ORDER_ID);
        SharedPreferencesUtils.getInstance(mContext).putStringValue("orderIdInDriving", orderId);
        getOrderDetail();
        initPeriodScanCallBack();
    }

    public void initMap() {
        mapView = (MapView) findViewById(R.id.car_inuse_map);
        mapView.showZoomControls(false);
        //MapView.setMapCustomEnable(true);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);//获取传感器管理服务
        if (mBaiduMap == null) {
            mBaiduMap = mapView.getMap();
            //设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
            mBaiduMap.setMyLocationEnabled(false);
            // 开启定位图层
            mBaiduMap.setMyLocationEnabled(true);
            mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
                    MyLocationConfiguration.LocationMode.NORMAL, true,
                    BitmapDescriptorFactory.fromResource(R.drawable.icon_mylocation)));
            //设置地图交互
            com.baidu.mapapi.map.UiSettings uiSettings = mBaiduMap.getUiSettings();
            uiSettings.setRotateGesturesEnabled(false);
            uiSettings.setOverlookingGesturesEnabled(false);
            uiSettings.setZoomGesturesEnabled(true);
            // 定位初始化
            mLocClient = new LocationClient(this);
            LocationClientOption option = new LocationClientOption();
            option.setIsNeedAddress(true);
            option.setIsNeedLocationDescribe(true);
            option.setOpenGps(true); // 打开gps
            option.setCoorType("bd09ll"); // 设置坐标类型
            option.setScanSpan(10000);
            mLocClient.setLocOption(option);
            mLocClient.registerLocationListener(myListener);
            mapStatusUtils = new MapStatusUtils(mBaiduMap);
            polygonUtils = new PolygonUtils(mBaiduMap);
            mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
                @Override
                public void onMapStatusChangeStart(MapStatus mapStatus) {
                }

                @Override
                public void onMapStatusChangeStart(MapStatus mapStatus, int i) {

                }

                @Override
                public void onMapStatusChange(MapStatus mapStatus) {
                    if (null != cityBoundsInfo) {
                        if (mapStatus.zoom < 14.5 && polygonUtils.polygonCoverList.size() == 0) {
                            polygonUtils.addBoundsCover(cityBoundsInfo);  //添加城市围栏填充色
                        } else if (mapStatus.zoom >= 14.5 && polygonUtils.polygonCoverList.size() != 0) {
                            polygonUtils.clearCover();   //清除城市围栏填充色
                        }
                    }
                }

                @Override
                public void onMapStatusChangeFinish(MapStatus mapStatus) {

                }
            });


            startLocation();
        }
    }

    private String message = "";

    @OnClick({R.id.imageButton_inUse_lockOff, R.id.imageButton_inUse_lockOn, R.id.textView_inUse_dropOffCar, R.id.title_tv_more,
            R.id.imageButton_inUse_findCar, R.id.imageView_refresh})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.imageButton_inUse_findCar:
                findCar(orderId, carId);
                break;
            case R.id.imageButton_inUse_lockOff:
                lockCarOff(orderId, carId);
                message = "正在锁车门...";
                carBleName = SharedPreferencesUtils.getInstance(mContext).getStringValue(SharedPreferencesKey.CAR_BLE_IDC);
                carBlePsw = SharedPreferencesUtils.getInstance(mContext).getStringValue(SharedPreferencesKey.CAR_BLE_PSW);
                if ((null != carBleName && !"".equals(carBleName)) && (null != carBlePsw && !"".equals(carBlePsw))) {
                    sendBle(ControlCmd.CONTROL_CLOSE_DOOR.getCmd(), carBlePsw,
                            MsgSendType.MSG_CONTROL);
                }
                break;
            case R.id.imageButton_inUse_lockOn:
                lockCarOn(orderId, carId);
                message = "正在开车门...";
                carBleName = SharedPreferencesUtils.getInstance(mContext).getStringValue(SharedPreferencesKey.CAR_BLE_IDC);
                carBlePsw = SharedPreferencesUtils.getInstance(mContext).getStringValue(SharedPreferencesKey.CAR_BLE_PSW);
                Log.i("carBlewName", carBleName + "  " + carBlePsw);
                if ((null != carBleName && !"".equals(carBleName)) && (null != carBlePsw && !"".equals(carBlePsw))) {
                    sendBle(ControlCmd.CONTROL_OPEN_DOOR.getCmd(), carBlePsw,
                            MsgSendType.MSG_CONTROL);
                }
                break;
            case R.id.title_tv_more:
                final InCarDialog inCarDialog = new InCarDialog(mContext);
                inCarDialog.setTitle(getString(R.string.dialogTitle));
                inCarDialog.setMessage("是否拨打客服电话" + ((MyApplication) getApplication()).getHotLine());
                inCarDialog.setYesOnclickListener("确定", new InCarDialog.onYesOnclickListener() {
                    @Override
                    public void onYesClick() {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_DIAL);
                        intent.setData(Uri.parse("tel:" + ((MyApplication) getApplication()).getHotLine()));
                        startActivity(intent);
                        inCarDialog.dismiss();
                    }
                });
                inCarDialog.setNoOnclickListener("取消", new InCarDialog.onNoOnclickListener() {
                    @Override
                    public void onNoClick() {
                        inCarDialog.dismiss();
                    }
                });
                inCarDialog.show();
                break;
            case R.id.textView_inUse_dropOffCar:
                Intent intent = new Intent(this, ReturnCarActivity.class);
                intent.putExtra("orderId", SharedPreferencesUtils.getInstance(mContext).getStringValue("orderIdInDriving"));
                intent.putExtra("carId", SharedPreferencesUtils.getInstance(mContext).getStringValue("carIdInDriving"));
                startActivity(intent);
                break;
            case R.id.imageView_refresh:
                if (curPosition != null) {
                    mapStatusUtils.animateMove(curPosition, 18, 600);
                }
                break;
        }
    }

    /**
     * 是否打开蓝牙
     */
    protected boolean isOpenBle;
    private String carBleName;//蓝牙名称
    private String carBlePsw;
    protected BluetoothLeDevice mDevice;
    OrderCmd currentOrderCmd = null;

    public BluetoothGattCharacteristic mBluetoothGattCharacteristic;


    protected synchronized void sendBle(String cmd, String pwd, MsgSendType type) {
        showLoadingDialog(message);
        if (BleUtil.isSupportBle(this)) {
            reSetBleManager();
            reSetParseManager();
            currentOrderCmd = initOrderCmd(cmd, pwd, type);
        }
        if (currentOrderCmd != null) {
            if (!ViseBluetooth.getInstance().isConnected()) {
                Logger.e("BleDriving", "BLE未连接");
                if (mDevice == null) {
                    scanBluetooth();
                    Logger.e("BleDriving", "重新扫描");
                } else {
                    Logger.e("BleDriving", "重新连接");
                    startConnect();
                }
            } else {
                Logger.e("BleDriving", "BLE已连接");
                if (mBluetoothGattCharacteristic != null) {
                    Logger.e("BleDriving", "发送指令");
                    BLESendManager.getInstance().send(currentOrderCmd, true);
                }
            }
        } else {
            dismissLoadingDialog();
        }
    }

    /**
     * 初始化当前的指令
     *
     * @param cmd
     * @param pwd
     * @param type
     */
    private OrderCmd initOrderCmd(String cmd, String pwd, MsgSendType type) {
        OrderCmd currentOrderCmd = null;
        if (type == MsgSendType.MSG_CONTROL) {
            currentOrderCmd = setOrderCmd(cmd, pwd, false, type, DeviceControlManager.getInstance()
                    .getDeviceControlCmd(cmd, pwd, ParseManager.getInstance().getmControlCmds()));
        } else if (type == MsgSendType.MSG_GPS) {
            currentOrderCmd = setOrderCmd(cmd, pwd, false, type, DeviceControlManager.getInstance()
                    .getGPSDataCmd());
        } else if (type == MsgSendType.MSG_STATE) {
            currentOrderCmd = setOrderCmd(cmd, pwd, false, type, DeviceControlManager.getInstance()
                    .getDeviceStateCmd());
        } else if (type == MsgSendType.MSG_CAR) {
            currentOrderCmd = setOrderCmd(cmd, pwd, false, type, DeviceControlManager.getInstance()
                    .getDeviceCarInfo());
        }
        return currentOrderCmd;
    }

    private void reSetBleManager() {
        BLESendManager.getInstance().reSet();
    }

    private void reSetParseManager() {
        ParseManager.getInstance().reSet();
    }

    /**
     * 初始化数据
     *
     * @param cmd
     * @param pwd
     * @param type
     * @param orderCmd
     * @param isNormalCmd 是否是6001应答
     * @return
     */
    private OrderCmd setOrderCmd(String cmd, String pwd, boolean isNormalCmd, MsgSendType type,
                                 OrderCmd orderCmd) {
        orderCmd.setType(type);
        orderCmd.setPwd(pwd);
        orderCmd.setCmdS(cmd);
        orderCmd.setNormalCode(isNormalCmd);
        return orderCmd;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == 1) {
                showLoadingDialog(message);
                startScan();
            }
        } else {
            dismissLoadingDialog();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 扫描BLE
     */
    protected void scanBluetooth() {
        if (BleUtil.isSupportBle(this)) {
            if (BleUtil.isBleEnable(this)) {
                Logger.e("BleDriving", "开始扫描");
                startScan();
            } else {
                dismissLoadingDialog();
                BleUtil.enableBluetooth(this, 1);
            }
        }
    }

    /**
     * 开始扫描
     */
    private void startScan() {
        ViseBluetooth.getInstance().setScanTimeout(8000).startScan(periodScanCallback);
    }

    /**
     * 结束扫描
     */
    private void stopScan() {
        ViseBluetooth.getInstance().stopScan(periodScanCallback);
    }

    /**
     * 蓝牙扫描成功或失败的回调
     */
    private PeriodScanCallback periodScanCallback;

    private void initPeriodScanCallBack() {
        if (Build.VERSION.SDK_INT < 18) {
            return;
        }
        periodScanCallback = new PeriodScanCallback() {
            @Override
            public void scanTimeout() {
                dismissLoadingDialog();
                ToastCompat.makeText(mContext, "未能找到车", Toast.LENGTH_LONG).setGravity(Gravity.CENTER, 0, 0).show();
                Logger.e("BleDriving", "扫描超时");
            }

            @Override
            public void onDeviceFound(final BluetoothLeDevice bluetoothLeDevice) {
                if (bluetoothLeDevice != null && carBleName.equals(bluetoothLeDevice.getName())) {
                    Logger.e("BleDriving", "BLE has found");
                    stopScan();
                    mDevice = bluetoothLeDevice;
                    // 开始连接
                    startConnect();
                }
            }
        };

    }


    /**
     * 开始连接
     */
    private void startConnect() {
        if (mDevice != null && !ViseBluetooth.getInstance().isConnected()) {
            if (BleUtil.isBleEnable(this)) {
                // 蓝牙打开
                Logger.e("BleDriving", "开始连接");
                ViseBluetooth.getInstance().connect(mDevice, false, connectCallback);
            } else {
                // 打开蓝牙
                Logger.e("BleDriving", "打开蓝牙");
                BleUtil.enableBluetooth(this, 1);
            }
        }
    }

    /**
     * 关闭连接
     */
    private void disConnect() {
        if (ViseBluetooth.getInstance().isConnected()) {
            Logger.e("BleDriving", "关闭连接");
            ViseBluetooth.getInstance().disconnect();
        }
    }

    /**
     * BLE连接状态的回调
     */
    private IConnectCallback connectCallback = new IConnectCallback() {
        @Override
        public void onConnectSuccess(BluetoothGatt gatt, int status) {
            Logger.e("BleDriving", "Connect Success!");
            if (gatt != null) {
                Logger.e("BleDriving", "initGattServices");
                initGattServices(gatt.getServices());
            }
            // 连接上立即发送数据会失败
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    //再次刷新请求信息
                    BLESendManager.getInstance().send(currentOrderCmd, true);
                }
            }, 400);
        }

        @Override
        public void onConnectFailure(BleException exception) {
            dismissLoadingDialog();
            ToastCompat.makeText(mContext, "连接失败", Toast.LENGTH_LONG).setGravity(Gravity.CENTER, 0, 0).show();
            Logger.e("BleDriving", "Connect Failure!");
        }

        @Override
        public void onDisconnect() {
            Logger.e("BleDriving", "Disconnect!");
        }
    };


    private void initGattServices(List<BluetoothGattService> gattServices) {

        // Loops through available GATT Services.
        for (final BluetoothGattService gattService : gattServices) {
            String uuid = gattService.getUuid().toString();
            boolean hasFoundWriteCharacteristic = false;
            boolean hasFoundReadCharacteristic = false;
            if (!StringUtils.isEmpty(uuid)
                    && (uuid.substring(0, uuid.indexOf("-")).toLowerCase()
                    .contains(writeServiceUUID))
                    || uuid.substring(0, uuid.indexOf("-")).toLowerCase().contains(readServiceUUID)) {
                // Loops through available Characteristics.
                final List<BluetoothGattCharacteristic> gattCharacteristics = gattService
                        .getCharacteristics();
                for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                    if (!StringUtils.isEmpty(gattCharacteristic.getUuid().toString())) {

                        if (gattCharacteristic.getUuid().toString().substring(0, uuid.indexOf("-"))
                                .toLowerCase().contains(writeCharacteristicUUID)) {
                            Logger.e("匹配成功");
                            mBluetoothGattCharacteristic = gattCharacteristic;
                            BLESendManager.getInstance().setBluetoothGattCharacteristic(
                                    gattCharacteristic);
                            hasFoundWriteCharacteristic = true;
                        }

                        if (gattCharacteristic.getUuid().toString().substring(0, uuid.indexOf("-"))
                                .toLowerCase().contains(readCharacteristicUUID)) {
                            ViseBluetooth.getInstance().enableCharacteristicNotification(
                                    gattCharacteristic, bleCallback, false);
                            hasFoundReadCharacteristic = true;
                        }
                    }
                }
            }
            if (hasFoundReadCharacteristic && hasFoundWriteCharacteristic) {
                break;
            }
        }
    }

    /**
     * 接收到数据的回调
     */
    private ICharacteristicCallback bleCallback = new ICharacteristicCallback() {
        @Override
        public void onSuccess(byte[] characteristic) {


            ParseManager.getInstance().parse(characteristic, new IParseResultCallback() {

                /**
                 * 收到完整指令
                 *
                 * @param serial
                 */
                @Override
                public void onSendNormalCmd(int serial) {
                    Logger.e("BleDriving", "发送6001");
                    if (mBluetoothGattCharacteristic != null) {
                        BLESendManager.getInstance().send(
                                setOrderCmd("", "", true, MsgSendType.MSG_NORMAL,
                                        DeviceControlManager.getInstance().getNormalCmd(serial)));
                    }
                }

                /**
                 * 收到6001
                 */
                @Override
                public void onCancleRepeatSend() {
                    Logger.e("BleDriving", "取消重复发送");
                    BLESendManager.getInstance().cancleRepeat();
                }

                /**
                 * 收到完整指令
                 *
                 * @param cmd
                 */
                @Override
                public void parseEnd(CommandBleDbBean cmd, String sendCode, int controlResultCode) {
                    Logger.e("BleDriving", "回复指令解析成功");
                    BLESendManager.getInstance().cancleTimeOut();
                    saveData(cmd, sendCode, controlResultCode);
                }

            });
            ViseBluetooth.getInstance().onDataParserCompleted();
        }

        @Override
        public void onFailure(BleException exception) {
            if (exception == null) {
                return;
            }
            Logger.e("BleDriving", "notify fail:" + exception.getDescription());
        }
    };

    /**
     * 保存数据库
     *
     * @param bleDbBean
     * @param sendCode          发送的控制指令，状态读取的时候是空值
     * @param controlResultCode 控制结果,超时是-1，状态读取时也是-1
     */

    private void saveData(CommandBleDbBean bleDbBean, String sendCode, int controlResultCode) {
        if (bleDbBean.getType() == 4) {
            // 控制
            parseControlResult(controlResultCode, sendCode);

        } else if (bleDbBean.getType() == 1) {
            // gps
        } else if (bleDbBean.getType() == 2) {
            // 状态

        } else if (bleDbBean.getType() == 3) {
            // 电量、里程等

        }

    }


    /**
     * @param result
     */
    private void parseControlResult(int result, String sendCode) {
        dismissLoadingDialog();
        switch (result) {
            case 0x00:// 成功
                ToastCompat.makeText(getApplicationContext(), "成功", Toast.LENGTH_LONG).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x01:// 总线忙
                ToastCompat.makeText(getApplicationContext(), "总线忙", Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x02:// 不支持
                ToastCompat.makeText(getApplicationContext(), "不支持", Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x04:// 收到控制时间超过有效期(10分钟)
            case 0x06:// 无效授权
                ToastCompat.makeText(getApplicationContext(), "无效授权", Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x19:// ON状态不执行（开门、锁门、寻车都有）
                ToastCompat.makeText(getApplicationContext(), "成功", Toast.LENGTH_SHORT)
                        .show();
                break;
            case 0x1A:// 原车PKE操作退出执行（仅开门有）
                ToastCompat.makeText(getApplicationContext(), "原车PKE操作退出执行（仅开门有）", Toast.LENGTH_SHORT)
                        .show();
                break;
            case 0x1B:// 门未关（仅锁门有）
                ToastCompat.makeText(getApplicationContext(), "请先关车门", Toast.LENGTH_LONG).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x1C:// 动作执行前执行失败（开门、锁门、寻车都有，出现此问题基本
                ToastCompat.makeText(getApplicationContext(), "动作执行前执行失败（开门、锁门、寻车都有，出现此问题基本",
                        Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x1D:// 中控锁未锁（仅锁门有）
                ToastCompat.makeText(getApplicationContext(), "请先关闭中控锁", Toast.LENGTH_LONG).setGravity(Gravity.CENTER, 0, 0).show();
                break;
            case 0x1E:// 开锁后中控锁为锁状态 (开锁门不成功)
                ToastCompat.makeText(getApplicationContext(), "开锁后中控锁为锁状态 (开锁门不成功)", Toast.LENGTH_SHORT)
                        .show();
                break;
            default:
                break;
        }
    }


    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
        mLocClient.start();
        //为系统的方向传感器注册监听器
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_UI);
    }


    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
        mLocClient.stop();
    }

    @Override
    protected void onStop() {
        //取消注册传感器监听
        mSensorManager.unregisterListener(this);
        super.onStop();
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        double x = sensorEvent.values[SensorManager.DATA_X];
        if (Math.abs(x - lastX) > 1.0) {
            mCurrentDirection = (int) x;
            if (curPosition != null) {
                locData = new MyLocationData.Builder()
                        .accuracy(mCurrentAccracy)
                        // 此处设置开发者获取到的方向信息，顺时针0-360
                        .direction(mCurrentDirection).latitude(curPosition.latitude)
                        .longitude(curPosition.longitude).build();
                mBaiduMap.setMyLocationData(locData);
            }
        }
        lastX = x;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }


    private void getOrderDetail() {
        showLoadingDialog();
        ApiStore.getInstance().getApiService(UrlConstant.Request.BASE_URL).getTravelDetail(((MyApplication) getApplication()).getRequestFieldMap(), orderId)
                .enqueue(new Callback<TravelDetailBean>() {
                    @Override
                    public void onResponse(Call<TravelDetailBean> call, Response<TravelDetailBean> response) {
                        if (response.isSuccessful() && response.body() != null) {
                            dismissLoadingDialog();
                            if (response.body().getStatus() == 200) {
                                TravelDetailBean.AttachmentBean result = response.body().getAttachment();
                                carId = result.getCarModel().getId();
                                SharedPreferencesUtils.getInstance(mContext).putStringValue("carIdInDriving", carId);
                                parkId = result.getCarModel().getParkId() + "";
                                carLicense = result.getCarModel().getLicenseTag();
                                tvInUseLicense.setText(carLicense);
                                tv_inUse_brand.setText(result.getCarModel().getBrand() + result.getCarModel().getModel());
                                Date date = new Date();
                                if (result.getStartBillingTime() <= 0) {
                                    count = 1;
                                } else {
                                    count = (int) ((date.getTime() - result.getStartBillingTime()) / 1000) + 1;
                                }
                                if (count < 0) {
                                    count = 1;
                                }
                                if (count > 86400) {
                                    textViewInUseTime.setText(getSpannableString(TimeUtils.formatMinPlusOne(count + "")));
                                } else {
                                    textViewInUseTime.setText(TimeUtils.formatSecondCount(count + "", 1));
                                }
                                countTime();
                                getBleInfo(response.body().getAttachment().getCarModel().getId());
                            } else {
                                ToastCompat.makeText(mContext, response.body().getMessage(), Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                            }
                        }
                    }

                    @Override
                    public void onFailure(Call<TravelDetailBean> call, Throwable t) {
                        dismissLoadingDialog();
                        ToastCompat.makeText(mContext, getResources().getString(R.string.badNetwork), Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                    }
                });

    }

    private void getBleInfo(String carId) {
        showLoadingDialog();
        ApiStore.getInstance().getApiService(UrlConstant.Request.BASE_URL).getCarBleInfo(((MyApplication) getApplication()).getRequestFieldMap(), carId)
                .enqueue(new Callback<CarBleBean>() {
                    @Override
                    public void onResponse(Call<CarBleBean> call, Response<CarBleBean> response) {
                        if (response.isSuccessful() && response.body() != null) {
                            dismissLoadingDialog();
                            if (response.body().getStatus() == 200) {
                                dismissLoadingDialog();
                                CarBleBaojiaBean carBleBaojia = new Gson().fromJson(response.body().getAttachment().getBluttoothInfo().toString(), CarBleBaojiaBean.class);
                                SharedPreferencesUtils.getInstance(mContext).putStringValue(SharedPreferencesKey.CAR_BLE_PSW,
                                        carBleBaojia.getCars().get(0).getPassword());
                                SharedPreferencesUtils.getInstance(mContext).putStringValue(SharedPreferencesKey.CAR_BLE_IDC,
                                        carBleBaojia.getCars().get(0).getIdc());
                            } else {
                                Log.i("bleinfo", response.body().getMessage() + "");
                            }
                        }
                    }

                    @Override
                    public void onFailure(Call<CarBleBean> call, Throwable t) {
                        dismissLoadingDialog();
                        ToastCompat.makeText(mContext, getResources().getString(R.string.badNetwork), Toast.LENGTH_SHORT).setGravity(Gravity.CENTER, 0, 0).show();
                    }
                });
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //确保是我们的请求
        if (requestCode == Constants.READ_LOCATION_PERMISSION_REQUEST) {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mLocClient.start();
            } else if (grantResults.length == 1 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                final InCarDialog inCarDialog = new InCarDialog(DrivingActivity.this);
                inCarDialog.setTitle(getString(R.string.dialogTitle));
                inCarDialog.setMessage("您已拒绝定位权限");
                inCarDialog.setYesOnclickListener("确定", new InCarDialog.onYesOnclickListener() {
                    @Override
                    public void onYesClick() {
                        inCarDialog.dismiss();
                        startLocation();
                    }
                });
                inCarDialog.setNoOnclickListener("取消", new InCarDialog.onNoOnclickListener() {
                    @Override
                    public void onNoClick() {
                        dismissLoadingDialog();
                        inCarDialog.dismiss();
                    }
                });
                inCarDialog.setCancelable(false);
                inCarDialog.show();

            } else {
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
        }
    }

    /**
     * 开车门 关车门 寻车后5秒内阻止用户点击
     */
    private void startProgress() {
        showLoadingDialog("请稍后");
        new CountDownTimer(5000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {

            }

            @Override
            public void onFinish() {
                dismissLoadingDialog();
            }
        }.start();
    }

    private void lockCarOn(final String orderId, final String carId) {
        if ((null == carBleName || "".equals(carBleName))) {
            showLoadingDialog(message);
        }

        ApiStore.getInstance().getApiService(UrlConstant.Request.BASE_URL).openCar(((MyApplication) getApplication()).getRequestFieldMap(), orderId, carId, "0").enqueue(new Callback<OperateBean>() {
            @Override
            public void onResponse(Call<OperateBean> call, Response<OperateBean> response) {
                if (response.isSuccessful() && response.body() != null) {
                    if ((null == carBleName || "".equals(carBleName))) {
                        dismissLoadingDialog();
                        if (response.body().getStatus() == 200) {
                            ToastCompat.makeText(mContext, "开车门成功", Toast.LENGTH_LONG).show();
                        } else {
                            ToastCompat.makeText(mContext, response.body().getMessage(), Toast.LENGTH_LONG).show();
                        }
                    }
                } else {
                    if ((null == carBleName || "".equals(carBleName))) {
                        dismissLoadingDialog();
                        ToastCompat.makeText(mContext, getResources().getString(R.string.serverError), Toast.LENGTH_LONG).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<OperateBean> call, Throwable t) {
                if ((null == carBleName || "".equals(carBleName))) {
                    dismissLoadingDialog();
                    ToastCompat.makeText(mContext, getResources().getString(R.string.shutCarDoorFailure), Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    private void lockCarOff(final String orderId, final String carId) {
        if ((null == carBleName || "".equals(carBleName))) {
            showLoadingDialog(message);
        }

        ApiStore.getInstance().getApiService(UrlConstant.Request.BASE_URL).lockCar(((MyApplication) getApplication()).getRequestFieldMap(), orderId, carId, "0").enqueue(new Callback<OperateBean>() {
            @Override
            public void onResponse(Call<OperateBean> call, Response<OperateBean> response) {
                if (response.isSuccessful() && response.body() != null) {
                    if ((null == carBleName || "".equals(carBleName))) {
                        dismissLoadingDialog();
                        if (response.body().getStatus() == 200) {
                            ToastCompat.makeText(mContext, "开车门成功", Toast.LENGTH_LONG).show();
                        } else {
                            ToastCompat.makeText(mContext, response.body().getMessage(), Toast.LENGTH_LONG).show();
                        }
                    }
                } else {
                    if ((null == carBleName || "".equals(carBleName))) {
                        dismissLoadingDialog();
                        ToastCompat.makeText(mContext, getResources().getString(R.string.serverError), Toast.LENGTH_LONG).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<OperateBean> call, Throwable t) {
                if ((null == carBleName || "".equals(carBleName))) {
                    dismissLoadingDialog();
                    ToastCompat.makeText(mContext, getResources().getString(R.string.shutCarDoorFailure), Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    public void findCar(String orderId, String carId) {
        showLoadingDialog("正在寻车...");
        ApiStore.getInstance().getApiService(UrlConstant.Request.BASE_URL).findCar(((MyApplication) getApplication()).getRequestFieldMap(), orderId, carId).enqueue(new Callback<OperateBean>() {
            @Override
            public void onResponse(Call<OperateBean> call, Response<OperateBean> response) {
                if (response.isSuccessful() && response.body() != null) {
                    if (response.body().getStatus() == 200) {
                        startProgress();
                    } else {
                        dismissLoadingDialog();
                        ToastCompat.makeText(mContext, response.body().getMessage(), Toast.LENGTH_LONG).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<OperateBean> call, Throwable t) {
                dismissLoadingDialog();
                ToastCompat.makeText(mContext, getResources().getString(R.string.findCarFailure), Toast.LENGTH_LONG).show();
            }
        });
    }

    private SpannableString getSpannableString(String dateString) {
        SpannableString spannableString = new SpannableString(dateString);
        spannableString.setSpan(new AbsoluteSizeSpan(14, true), dateString.indexOf("天"), dateString.indexOf("天") + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(new AbsoluteSizeSpan(14, true), dateString.indexOf("小时"), dateString.indexOf("小时") + 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(new AbsoluteSizeSpan(14, true), dateString.indexOf("分钟"), dateString.indexOf("分钟") + 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

    private void countTime() {
        if (task == null) {
            task = new TimerTask() {
                public void run() {
                    Message message = new Message();
                    message.what = 1;
                    handler.sendEmptyMessage(1);
                }
            };
        }
        if (timer == null) {
            timer = new Timer(true);
            timer.schedule(task, 0, 1000); //延时0ms后执行，1000ms执行一次
        }
        acquireWakeLock();
    }

    private void startLocation() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, Constants.READ_LOCATION_PERMISSION_REQUEST);
            } else {
                mLocClient.start();
            }
        } else {
            mLocClient.start();
        }

    }

    @Override
    public void onTimeOut(OrderCmd orderCmd, int type) {

    }

    @Override
    public void onNormalCmdSendEnd() {

    }

    @Override
    public void onStartSend() {

    }

    private boolean firstLocationError = true;

    //定位结果监听
    private class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            if (null != bdLocation && (bdLocation.getLocType() == BDLocation.TypeGpsLocation || bdLocation.getLocType() == BDLocation.TypeNetWorkLocation)) {

                bdLocation = LocationFilter.Algorithm(bdLocation);//根据历史定位，对定位的结果平滑过滤
                curPosition = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());// 更新定位
                ((MyApplication) getApplication()).setCurPosition(curPosition.latitude + "", curPosition.longitude + "");
                mCurrentAccracy = bdLocation.getRadius();
                locData = new MyLocationData.Builder()
                        .accuracy(mCurrentAccracy)
                        .direction(bdLocation.getDirection())// 此处设置开发者获取到的方向信息，顺时针0-360
                        .latitude(curPosition.latitude)
                        .longitude(curPosition.longitude).build();

                mBaiduMap.setMyLocationData(locData);
                if (isFirstLocation) {//首次成功的定位
                    isFirstLocation = false;
                    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder()
                            .target(curPosition)
                            .zoom(18.0f).build()));
                    if (bdLocation.getCityCode() != null && !bdLocation.getCityCode().equals("")) {
                        ((MyApplication) getApplication()).setAreaCode(bdLocation.getCityCode());
                        ((MyApplication) getApplication()).setAdCode(bdLocation.getCityCode());
                        getFenceListData();
                    }
                }
            } else {
                if (firstLocationError) {
                    firstLocationError = false;
                    ToastCompat.makeText(mContext, "获取位置信息失败，请重试...", Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    private void getFenceListData() {
        ApiStore.getInstance().getApiService(UrlConstant.Request.BASE_URL).getFenceList(((MyApplication) getApplication()).getRequestFieldMap()).enqueue(new Callback<CityBoundBean>() {
            @Override
            public void onResponse(Call<CityBoundBean> call, Response<CityBoundBean> response) {
                if (response.isSuccessful() && response.body() != null) {
                    if (response.body().getStatus() == 200) {
                        List<List<CityBoundBean.AttachmentBean>> attachment = response.body().getAttachment();
                        if (attachment != null) {
                            cityBoundsInfo = response.body().getAttachment();
                            if (polygonUtils != null) {
                                polygonUtils.addBounds(cityBoundsInfo);
                            }
                        }
                    }
                }
            }

            @Override
            public void onFailure(Call<CityBoundBean> call, Throwable t) {

            }
        });
    }

    @Override
    public void onBackPressed() {
        exit();
    }

    private void exit() {
        if (!isExit) {
            isExit = true;
            ToastCompat.makeText(this, "订单进行中，再按一次退出应用", Toast.LENGTH_LONG).show();
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    isExit = false;
                }
            }, 3000);
        } else {
            releaseWakeLock();
            AppManager.getAppManager().AppExit(mContext);
        }
    }

    private void acquireWakeLock() {
        if (null == wakeLock) {
            PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "PostLocationService");
            if (null != wakeLock) {
                wakeLock.acquire();
            }
        }
    }

    //释放设备电源锁
    private void releaseWakeLock() {
        if (null != wakeLock) {
            wakeLock.release();
            wakeLock = null;
        }
    }


    @Override
    protected void onDestroy() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if (task != null) {
            task.cancel();
            task = null;
        }
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        MapView.setMapCustomEnable(false);
        mapView.onDestroy();
        super.onDestroy();
    }
}